package 
{
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.utils.getTimer;

	public class TraceManager
	{
		// 
		// For each trace statement, you should specify how important it is.  These are the constants that define the trace levels.
		//
		
		private static var TL_OFF:uint = 0;
		public  static var TL_URGENT:uint = 1;
		public  static var TL_HIGH:uint = 2;
		public  static var TL_MEDIUM:uint = 3;
		public  static var TL_LOW:uint = 4;
		
		//
		// These are the components that the trace system knows about.  You should add  yourself a new component here if you want
		// to separate out its tracing behaviors from the other parts of the system.
		//
		
		public static var WINDOW_STATE_MGR:String = "WindowStateManager";
		public static var COMMANDER_MGR:String = "CommanderManager";
		public static var SIMPLE_ANIMATOR:String = "SimpleAnimator";
		public static var SIMPLE_PROVIDER:String = "SimpleProvider";
		public static var EXPOSE_SCROLLER:String = "ExposeScroller";
		
		//
		// This is the map of what trace levels should be shown for each component.  You can configure this as you're working
		// to see the amount of trace information that's appropriate for what you're doing.
		//
		
		public static var m_traceLevels:Object = {
			WindowStateManager:TL_MEDIUM,
			CommanderManager:TL_HIGH,
			SimpleAnimator:TL_MEDIUM,
			SimpleProvider:TL_OFF,
			ExposeScroller:TL_MEDIUM
		};
			
		//
		// This class is the gateway through which all application tracing should flow.  It looks in the trace levels map
		// and decides how much trace information really should be displayed.
		//
		
		private static function makePreamble(component:String):String
		{
			var now:uint = getTimer();
			return component.concat("@",now,":");
		}
		
		public static function trace_msg(component:String, tracelevel:uint, ...args):void
		{
			if( null == m_traceLevels[component] )
			{
				// Someone is attempting to trace an undefined component.  Just ignore them.
				return; 
			}

			if( m_traceLevels[component] >= tracelevel )
			{
				args.unshift(makePreamble(component));
				trace.apply(null, args);
			}
		}

		public static function trace_event(component:String, tracelevel:uint, e:Event):void
		{
			if( null == m_traceLevels[component] )
			{
				// Someone is attempting to trace an undefined component.  Just ignore them.
				return; 
			}
			
			if( m_traceLevels[component] >= tracelevel )
			{
				// Show only the last three items in the target hierarchy.
				var target:Array = e.target.toString().split(".");
				for( var i:Number = 0; i < (target.length - 3); i++)
					target.shift();
				
				if( e is MouseEvent )
					trace(makePreamble(component),"type=",e.type,"target=",target.join("."),"localX=",(e as MouseEvent).localX,"localY=",(e as MouseEvent).localY);
				else
					trace(makePreamble(component),"type=",e.type,"target=",target.join("."));
			}
		}

	}
}